<script setup>
import { Button as AButton, Form, Input, Modal, Select, message, Compact as SpaceCompact, List, ListItem, ListItemMeta, Result, Drawer, TypographyParagraph } from 'ant-design-vue';
import { SoundOutlined, FileTextOutlined, CheckCircleFilled, DeleteOutlined, LoadingOutlined, ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { reactive, ref, h } from 'vue';
import { ipc } from '../utils/ipcRenderer';
import { pinyin } from 'pinyin-pro';
import ipcApiRoute from '../api/index';

const viewNum = ref(0);

const versionOptions = [
  { value: '55', label: '1.21.5-pre1及以上' },
  { value: '54', label: '1.21.5 25w10a' },
  { value: '53', label: '1.21.5 25w08a~25w09b' },
  { value: '52', label: '1.21.5 25w07a' },
  { value: '51', label: '1.21.5 25w06a' },
  { value: '50', label: '1.21.5 25w05a' },
  { value: '49', label: '1.21.5 25w04a' },
  { value: '48', label: '1.21.5 25w03a' },
  { value: '47', label: '1.21.5 25w02a' },
  { value: '46', label: '1.21.4' },
  { value: '45', label: '1.21.4 24w46a' },
  { value: '44', label: '1.21.4 24w45a' },
  { value: '43', label: '1.21.4 24w44a' },
  { value: '42', label: '1.21.3' },
  { value: '41', label: '1.21.2-pre1~pre2' },
  { value: '40', label: '1.21.2 24w40a' },
  { value: '39', label: '1.21.2 24w38a~24w39a' },
  { value: '38', label: '1.21.2 24w37a' },
  { value: '37', label: '1.21.2 24w36a' },
  { value: '36', label: '1.21.2 24w34a~24w35a' },
  { value: '35', label: '1.21.2 24w33a' },
  { value: '34', label: '1.21.1' },
  { value: '33', label: '1.21 24w18a~24w20a' },
  { value: '32', label: '1.20.6' },
  { value: '31', label: '1.20.5-pre4' },
  { value: '30', label: '1.20.5 24w12a' },
  { value: '29', label: '1.20.5 24w11a' },
  { value: '28', label: '1.20.5 24w09a~24w10a' },
  { value: '26', label: '1.20.5 24w06a~24w07a' },
  { value: '25', label: '1.20.5 24w05a~24w05b' },
  { value: '24', label: '1.20.5 24w03a~24w04a' },
  { value: '22', label: '1.20.4 23w51b' },
  { value: '21', label: '1.20.3 23w45a~23w46a' },
  { value: '20', label: '1.20.3 23w43a~23w44a' },
  { value: '19', label: '1.20.3 23w42a' },
  { value: '18', label: '1.20.3 23w41a' },
  { value: '17', label: '1.20.2-pre1' },
  { value: '16', label: '1.20.2 23w31a' },
  { value: '15', label: '1.20.1' },
  { value: '14', label: '1.20 23w14a~23w16a' },
  { value: '13', label: '1.20 23w13a' },
  { value: '12', label: '1.19.4 23w07a' },
  { value: '11', label: '1.19.3 22w42a~22w44a' },
  { value: '9', label: '1.19~1.19.2' },
  { value: '8', label: '1.18~1.18.2' },
  { value: '7', label: '≤1.17.1' },
  { value: '6', label: '≤1.16.5' },
  { value: '5', label: '≤1.16.1' },
  { value: '4', label: '≤1.14.4' },
  { value: '3', label: '≤1.12.2' },
  { value: '2', label: '≤1.10.2' },
  { value: '1', label: '≤1.8.9' },
];

const formState = reactive({
  name: '',
  description: '',
  version: undefined,
});

const rules = {
  name: [
    { required: true, message: '请输入音乐包名称' },
    { pattern: /^[^0-9].*$/, message: '音乐包名称不能以数字开头' }
  ],
  version: [{ required: true, message: '请输入游戏版本' }]
};

const Msgkey = "createSoundsPack"

const onSubmit = async () => {
  try {
    const result = await form.validate();
    console.log(result);
    createSoundsPack(result)
    message.loading({
      content: '创建中...',
      key: Msgkey,
    });
  } catch (error) {
    console.error('提交失败:', error);
  }
};

const onCancel = () => {
  form.resetFields();
};

const createSoundsPack = async (value) => {
  try {
    // 第一次尝试创建音乐包
    const result = await ipc.invoke(ipcApiRoute.createSoundsPack, value);

    // 处理不同状态的响应
    switch (result?.status) {
      case 201: // 音乐包已存在
        await handleExistingPack(value);
        break;
      case 200: // 创建成功
        await handleSuccess(result);
        break;
      default: // 其他情况视为失败
        handleError();
    }
  } catch (error) {
    console.error('创建音乐包失败:', error);
    handleError();
  }
};

// 处理已存在音乐包的情况
const handleExistingPack = (value) => {
  return new Promise((resolve) => {
    Modal.confirm({
      title: '音乐包重复',
      icon: h(ExclamationCircleOutlined),
      content: h('div', { style: 'color:red;' }, '音乐包已经存在，是否覆盖？'),
      async onOk() {
        try {
          const result = await ipc.invoke(ipcApiRoute.createYSoundsPack, value);
          await handleSuccess(result);
          resolve();
        } catch (error) {
          handleError();
          resolve();
        }
      }
    });
  });
};

// 处理创建成功的情况
const handleSuccess = async (result) => {
  console.log(result.data);
  message.success({
    content: '创建音乐包成功',
    key: Msgkey,
  });
  viewNum.value = 1;
};

// 处理错误情况
const handleError = () => {
  message.error({
    content: '创建音乐包失败',
    key: Msgkey,
  });
};

const form = Form.useForm(formState, rules);
const audioFiles = ref([]);
const audioCheckFiles = ref([]);
const isProcessing = ref(false);

// 添加音频文件
const addAudioFile = async () => {
  try {
    // 调用后端方法选择音频文件
    const result = await ipc.invoke(ipcApiRoute.selectAudioFiles);
    if (result && result.status === 'ok' && result.data) {
      // 将新选择的文件添加到列表中
      audioFiles.value = [...audioFiles.value, ...result.data];
      message.success(`成功添加${result.data.length}个音频文件`);
    }
  } catch (error) {
    console.error('添加音频文件失败:', error);
    message.error('添加音频文件失败');
  }
};

// 移除音频文件
const removeAudioFile = (index) => {
  audioFiles.value.splice(index, 1);
  message.success('已移除音频文件');
};

// 处理音频文件
const processAudioFiles = async () => {
  if (audioFiles.value.length === 0) {
    message.warning('请先添加音频文件');
    return;
  }

  isProcessing.value = true;
  audioCheckFiles.value = [];

  try {
    // 处理每个音频文件
    for (const file of audioFiles.value) {
      // 处理文件名
      let newName = processFileName(file.name);

      // 处理文件格式
      let newType = 'ogg';
      let needConvert = file.type.toLowerCase() !== 'ogg';

      // 添加到处理后的文件列表，初始状态为处理中
      const audioFile = {
        originalPath: file.path,
        originalName: file.name,
        name: `${newName}.${newType}`,
        needConvert: needConvert,
        status: 'processing', // 添加状态：processing, completed, error
        processed: false
      };

      audioCheckFiles.value.push(audioFile);

      // 模拟处理延迟
      const result = await ipc.invoke(ipcApiRoute.toOggSoundsPack, { name: formState.name, path: file.path, value: newName });
      if (result && result.status === 200) {
        // 模拟处理完成，更新状态
        const index = audioCheckFiles.value.findIndex(item =>
          item.originalPath === audioFile.originalPath &&
          item.originalName === audioFile.originalName
        );

        if (index !== -1) {
          audioCheckFiles.value[index].status = 'completed';
          audioCheckFiles.value[index].processed = true;
        }
      }
    }

    message.success('音频文件处理完成');
    isProcessing.value = false;
  } catch (error) {
    console.error('处理音频文件失败:', error);
    message.error('处理音频文件失败');
    isProcessing.value = false;

    // 将所有未完成处理的文件标记为错误状态
    audioCheckFiles.value.forEach(file => {
      if (file.status === 'processing') {
        file.status = 'error';
      }
    });
  }
};

// 处理文件名
const processFileName = (fileName) => {
  // 移除扩展名
  const nameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));

  // 判断是否为中文
  const isChinese = /[\u4e00-\u9fa5]/.test(nameWithoutExt);

  if (isChinese) {
    // 中文名称转拼音并取首字母
    let result = pinyin(nameWithoutExt, { toneType: 'none', type: 'array' })
      .map(word => word.charAt(0))
      .join('')
      .toLowerCase()
      .replace(/[^a-z0-9]/g, ''); // 移除非字母数字字符

    // 限制长度为5个字符
    if (result.length > 5) {
      result = result.substring(0, 5);
    }

    return result;
  } else {
    // 英文名称缩写处理
    let result = nameWithoutExt
      .replace(/[^a-zA-Z0-9]/g, '') // 移除非字母数字字符
      .toLowerCase();

    // 如果长度超过5个字符，进行缩写
    if (result.length > 5) {
      // 提取首字母和重要字符
      const firstChar = result.charAt(0);
      const lastChar = result.charAt(result.length - 1);

      if (result.length <= 3) {
        // 如果长度小于等于3，直接返回
        return result;
      } else if (result.length <= 5) {
        // 如果长度小于等于5，直接返回
        return result;
      } else {
        // 取首字母、中间字符和尾字母，再加上两个重要位置的字符
        const pos1 = Math.floor(result.length / 3);
        const pos2 = Math.floor(result.length * 2 / 3);
        result = firstChar + result.charAt(pos1) + result.charAt(pos2) + lastChar;

        // 如果还是超过5个字符，截取前5个
        if (result.length > 5) {
          result = result.substring(0, 5);
        }
      }
    }

    return result;
  }
};

const isZip = ref(0);
const isviewCommand = ref(false);
const viewCommandList = ref([]);
const CommandList = ref([]);
const viewZip = () => {
  viewNum.value = 3;
  toZip();
}
const toZip = async () => {
  try {
    isZip.value = 0;
    const result = await ipc.invoke(ipcApiRoute.toSoundsPack, { name: formState.name });
    if (result && result.status === 200 && result.data) {
      message.success('打包成功');
      console.log(result.data);
      CommandList.value = result.data.cmd.keyValue
      isZip.value = 1;
    }
  } catch (error) {
    console.error('打包失败:', error);
    message.error('打包失败');
    isZip.value = 2;
  }
};

/**
 * 生成Minecraft播放音乐的命令
 * @param {string} value - 音乐的标识符
 * @returns {string} 返回完整的播放命令
 */
const toCommand = (value) => {
  return `/playsound ${value} record @a ~ ~ ~ 10000`
}

const openFolder = async () => {
  await ipc.invoke(ipcApiRoute.openFolder);
}

/**
 * 查看并生成Minecraft音乐播放命令列表
 * 将音频文件和对应的命令组合成列表展示
 */
const viewCommand = () => {
  // 打开命令查看抽屉
  isviewCommand.value = true;

  // 重置命令列表
  viewCommandList.value = [];

  // 检查必要数据是否存在
  if (!audioFiles.value.length || !CommandList.value.length) {
    message.warning('没有可用的音频文件或命令');
    return;
  }

  try {
    // 生成命令列表,将音频文件名和对应的播放命令组合
    viewCommandList.value = audioFiles.value.map((file, index) => ({
      name: file.name,
      cmd: toCommand(CommandList.value[index])
    }));
  } catch (error) {
    console.error('生成命令列表失败:', error);
    message.error('生成命令列表失败');
  }
};

const Allback = () => {
  form.resetFields();
  viewNum.value = 0;
  audioFiles.value = [];
  audioCheckFiles.value = []
  viewCommandList.value = []
  CommandList.value = []
}
</script>

<template>
  <div class="create">
    <div class="title">
      <h2 v-if="viewNum == 0">填写信息</h2>
      <h2 v-if="viewNum == 1">添加音频</h2>
      <h2 v-if="viewNum == 2">处理音频</h2>
      <h2 v-if="viewNum == 3">进行打包</h2>
    </div>
    <Drawer title="查看命令" placement="bottom" :closable="true" v-model:open="isviewCommand">
      <List style="overflow-y: auto" item-layout="horizontal" :data-source="viewCommandList">
        <template #renderItem="{ item, index }">
          <ListItem>
            <ListItemMeta>
              <template #description>
                <TypographyParagraph copyable>{{ item.cmd }}</TypographyParagraph>
              </template>
            </ListItemMeta>
          </ListItem>
        </template>
        <template #empty>
          <div style="text-align: center; padding: 20px 0;">
            暂无音频文件，请点击上方按钮添加
          </div>
        </template>
      </List>
    </Drawer>
    <div class="card">
      <div class="view" v-if="viewNum == 0">
        <Form layout="vertical" :model="formState" @submit="onSubmit">
          <Form.Item name="name" label="音乐包名称" :rules="rules.name">
            <Input v-model:value="formState.name" placeholder="音乐包名称">
            <template #prefix>
              <SoundOutlined />
            </template>
            </Input>
          </Form.Item>
          <Form.Item name="description" label="音乐包简介">
            <Input v-model:value="formState.description" show-count :maxlength="10" placeholder="音乐包简介">
            <template #prefix>
              <FileTextOutlined />
            </template>
            </Input>
          </Form.Item>
          <Form.Item name="version" label="游戏版本" :rules="rules.version">
            <Select v-model:value="formState.version" placeholder="请选择游戏版本" :options="versionOptions" />
          </Form.Item>
          <SpaceCompact block style="width: 100%;">
            <AButton block @click="onCancel">取消</AButton>
            <AButton type="primary" block html-type="submit">确定</AButton>
          </SpaceCompact>
        </Form>
      </div>
      <div class="view" v-if="viewNum == 1">
        <SpaceCompact block style="width: 100%;">
          <AButton block @click="addAudioFile">添加音频文件</AButton>
          <AButton type="primary" @click="viewNum = 2" block>确定</AButton>
        </SpaceCompact>
        <div class="autolist">
          <List style="overflow-y: auto" item-layout="horizontal" :data-source="audioFiles">
            <template #renderItem="{ item, index }">
              <ListItem>
                <template #actions>
                  <a key="list-remove" @click="() => removeAudioFile(index)">
                    <DeleteOutlined /> 移除
                  </a>
                </template>
                <ListItemMeta :description="item.name">
                </ListItemMeta>
              </ListItem>
            </template>
            <template #empty>
              <div style="text-align: center; padding: 20px 0;">
                暂无音频文件，请点击上方按钮添加
              </div>
            </template>
          </List>
        </div>
      </div>
      <div class="view" v-if="viewNum == 2">
        <SpaceCompact block style="width: 100%;">
          <AButton block @click="processAudioFiles" :loading="isProcessing">处理音频</AButton>
          <AButton type="primary" block @click="viewZip" :disabled="audioCheckFiles.length === 0 || isProcessing">下一步
          </AButton>
        </SpaceCompact>
        <div class="autolist">
          <List style="overflow-y: auto" item-layout="horizontal" :data-source="audioCheckFiles">
            <template #renderItem="{ item }">
              <ListItem>
                <template #actions>
                  <!-- 根据处理状态显示不同图标 -->
                  <span v-if="item.status === 'processing'">
                    <LoadingOutlined style="color: #1890ff" /> 处理中
                  </span>
                  <span v-else-if="item.status === 'completed'">
                    <CheckCircleFilled style="color: #52c41a" /> 已完成
                  </span>
                  <span v-else-if="item.status === 'error'">
                    <DeleteOutlined style="color: #ff4d4f" /> 处理失败
                  </span>
                  <span v-else>
                    <LoadingOutlined style="color: #1890ff" v-if="item.needConvert" />
                    <span v-if="item.needConvert">需转换</span>
                    <CheckCircleFilled style="color: #52c41a" v-else />
                  </span>
                </template>
                <ListItemMeta :description="`${item.originalName} → ${item.name}`">
                </ListItemMeta>
              </ListItem>
            </template>
            <template #empty>
              <div style="text-align: center; padding: 20px 0;">
                <LoadingOutlined v-if="isProcessing" style="margin-right: 8px" />
                {{ isProcessing ? '正在处理音频文件...' : '请点击上方按钮处理音频文件' }}
              </div>
            </template>
          </List>
        </div>
      </div>
      <div class="view" v-if="viewNum == 3">
        <Result :status="isZip === 1 ? 'success' : isZip === 2 ? 'error' : 'info'"
          :title="isZip === 1 ? '打包完成' : isZip === 2 ? '打包失败' : '打包中...'"
          :sub-title="isZip === 1 ? '音乐包已生成' : isZip === 2 ? '请重试' : '请稍后'">
          <template #icon>
            <LoadingOutlined v-if="isZip === 0" spin />
            <CheckCircleFilled v-if="isZip === 1" style="color: #52c41a" />
            <ExclamationCircleOutlined v-if="isZip === 2" style="color: #ff4d4f" />
          </template>
          <template #extra>
            <SpaceCompact>
              <AButton type="primary" v-if="isZip === 1" @click="Allback">
                完成
              </AButton>
              <AButton v-if="isZip === 1" type="primary" @click="openFolder">
                打开文件夹
              </AButton>
              <AButton v-if="isZip === 1" @click="viewCommand">
                查看命令
              </AButton>
              <AButton v-if="isZip === 2" type="primary" danger @click="toZip">
                重试
              </AButton>
            </SpaceCompact>
          </template>
        </Result>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.create {
  .title {
    h2 {
      font-weight: bold;
    }

    margin-bottom: 10px;
  }

  .card {
    .view {
      padding: 10px;
    }

    .autolist {
      overflow-y: auto;
      max-height: 250px;
      margin-top: 10px;
    }

    padding: 10px;
    width: 400px;
    height: 320px;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 12px;
    background-color: #fff;
  }

  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
</style>